package main

import (
	"database/sql"
	"fmt"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"log"
	"time"
)

// UserInfo 用户信息
type UserInfo struct {
	ID         uint
	Name       string
	Gender     string
	Hobby      string
	CrateTime  time.Time
	ModifyTime time.Time
}

func InitMySQL() *gorm.DB {
	db, err := gorm.Open("mysql", "root:123456@tcp(192.168.149.133:3306)/mydatabase?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		log.Fatalln("gorm open mysql failed, error: ", err)
	} else {
		log.Println("connect to mysql success")
	}
	return db
}

// 自动迁移与增删改查
func MySqlADCSDemo(db *gorm.DB) {
	//自动迁移
	//db.AutoMigrate(&UserInfo{})
	//u1 := &UserInfo{
	//	ID:         1003,
	//	Name:       "zhangsan",
	//	Gender:     "male",
	//	Hobby:      "football",
	//	CrateTime:  time.Now(),
	//	ModifyTime: time.Now(),
	//}
	//
	//u2 := &UserInfo{
	//	ID:         1004,
	//	Name:       "lisi",
	//	Gender:     "female",
	//	Hobby:      "ball",
	//	CrateTime:  time.Now(),
	//	ModifyTime: time.Now(),
	//}
	//插入
	//db.Create(u1)
	//db.Create(u2)
	//查询
	var uu UserInfo
	db.Find(&uu, "id=?", 1001)
	fmt.Println("uu = ", uu)

	//更新
	db.Model(&UserInfo{}).Update("hobby", "sing a song").Where("id=?", 1001)

	//删除
	//db.Delete(&UserInfo{})
}

// 使用gorm.Model
type student struct {
	gorm.Model
	Name string
}

// 自定义类型
type User struct {
	gorm.Model
	Name         string
	Age          sql.NullInt64
	Birthday     *time.Time
	Email        string  `gorm:"type:varchar(100);unique_index"`
	Role         string  `gorm:"size:255"`        // 设置字段大小为255
	MemberNumber *string `gorm:"unique;not null"` // 设置会员号（member number）唯一并且不为空
	Num          int     `gorm:"AUTO_INCREMENT"`  // 设置 num 为自增类型
	Address      string  `gorm:"index:addr"`      // 给address字段创建名为addr的索引
	IgnoreMe     int     `gorm:"-"`               // 忽略本字段
}

// 主键
type User1 struct {
	ID   string // 名为`ID`的字段会默认作为表的主键
	Name string
}

// 使用`AnimalID`作为主键
type Animal struct {
	AnimalID int64 `gorm:"primary_key"`
	Name     string
	Age      int64
}

func Primarykey(db *gorm.DB) {
	db.AutoMigrate(&User1{})
	db.AutoMigrate(&Animal{})
}

// 表名，默认是结构体名称的负数
type User2 struct {
	Role string
}

func (u *User2) TableName() string {
	if u.Role == "admin" {
		return "user_2"
	} else {
		return "user_22"
	}
}
func SpecifyTableName(db *gorm.DB) {
	//db.AutoMigrate(&User2{})
	//也可以通过Table方法指定表明
	db.Table("user_222").CreateTable(&User2{})
}

// 列名
// 列名由字段名称进行下划线分割来生成
type User3 struct {
	ID        uint      // column name is `id`
	Name      string    // column name is `name`
	Birthday  time.Time // column name is `birthday`
	CreatedAt time.Time // column name is `created_at`
}
type User4 struct {
	ID        uint      // column name is `id`
	Name      string    // column name is `name`
	Birthday  time.Time // column name is `birthday`
	CreatedAt time.Time // column name is `created_at`
	UpdatedAt time.Time
	DeletedAt time.Time
}

type User5 struct {
	ID        uint      // column name is `id`
	Name      string    // column name is `name`
	Birthday  time.Time // column name is `birthday`
	CreatedAt time.Time // column name is `created_at`
	UpdatedAt time.Time
}

// 可以使用结构体tag指定列名：
type Animal1 struct {
	AnimalId int64     `gorm:"column:beast_id"`         // set column name to `beast_id`
	Birthday time.Time `gorm:"column:day_of_the_beast"` // set column name to `day_of_the_beast`
	Age      int64     `gorm:"column:age_of_the_beast"` // set column name to `age_of_the_beast`
}

func ColumnAlias(db *gorm.DB) {
	//db.AutoMigrate(&User3{})
	//db.AutoMigrate(&Animal1{})
	db.AutoMigrate(&User4{})
}

func CUDTest(db *gorm.DB) {
	//如果模型有 CreatedAt字段，该字段的值将会是初次创建记录的时间。
	//db.Create(&User3{
	//	ID:       1001,
	//	Name:     "zhangsan",
	//	Birthday: time.Now(),
	//})
	//db.AutoMigrate(&User4{}).DropTable()
	//db.Create(&User4{
	//	ID:        1001,
	//	Name:      "zhangsan",
	//	Birthday:  time.Now(),
	//	DeletedAt: time.Now(),
	//})
	//var uu User4
	//db.Find(&uu, "name=?", "zhangsan")
	//db.Model(&uu).Update("name", "lisi")
	//db.Delete(&uu)
	//db.AutoMigrate(&User5{})
	//u2 := &User5{
	//	ID:       1005,
	//	Name:     "lisi",
	//	Birthday: time.Now(),
	//}
	//db.Create(&u2)
	//db.Model(&u1).Update("name", "zhangwu")
	//db.Model(&User5{}).Where("id=?", 1002).Update("name", "zhaoliu")
	//db.Model(&User5{}).Create(u2)
	var uu5 []User5
	db.Model(&User5{}).Where("name=?", "lisi").Find(&uu5)
	fmt.Println(uu5)

}
func main() {
	db := InitMySQL()
	defer db.Close()
	//MySqlADCSDemo(db)
	//Primarykey(db)
	//SpecifyTableName(db)
	//ColumnAlias(db)
	CUDTest(db)
}
